#!/usr/sbin/rsct/perl5/bin/perl 
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 1999,2002 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# "@(#)08   1.23   src/rsct/registry/cli/bin/rmsrrow.perl, srcli, rsct_rpyxh, rpyxht1f3 2/22/01 16:25:34"
######################################################################
#                                                                    #
# Module: rmsrrow                                                    #
#                                                                    #
# Purpose:                                                           #
#   rmsrrow - Remove rows from a System Registry table.              #
#                                                                    #
# Syntax:                                                            #
#   rmsrrow [-h][-TV] Table 'Selection_string'                       #
#                                                                    #
# Flags:                                                             #
#   -h  Help. Writes this command's usage statement to stdout.       #
#   -T  Trace. Writes this command's trace messages to stderr.       #
#   -V  Verbose. Writes this command's verbose messages to stderr.   #
#                                                                    #
# Operands:                                                          #
#   Table   Name of the table to have rows removed. The operand can  #
#           contain an absolute or relative path.                    #
#   Selection_string Search string to be used in identifying row(s)  #
#           to be removed. Must be enclosed in single quotes.        #
#                                                                    #
# Description:                                                       #
#   The rmsrrow command removes all rows from a System Registry      #
#   table that match Selection_string criteria given on the command  #
#   line. Criteria is similar to that used in lssrtbl or selectsr.   #
#   Refer to the System Registry C API for a listing of the BNF      #
#   grammar needed for the string. Also refer to the srcli man page. #
#                                                                    #
#   This function is atomic in that if multiple rows match the       #
#   Selection_string criteria, then all will be removed, or the table#
#   will be left unaltered. If no rows are found to match the        #
#   Selection_string, then the table is left unaltered.  See the     #
#   Examples section for some valid Selection_strings.               #
#                                                                    #
#   To list the data of the table, use either the lssrtbl or         #
#   selectsr command.                                                #
#                                                                    #
# Exit Values:                                                       #
#   0  SR_CLI_SUCCESS        Command completed successfully.         #
#   1  SR_CLI_REGISTRY_ERROR Command terminated due to an underlying #
#                            System Registry error.                  #
#   2  SR_CLI_ERROR          Command terminated due to an underlying #
#                            error in the command script.            #
#   3  SR_CLI_BAD_OPERAND    Command terminated due to user          #
#                            specifying a bad operand.               #
#   4  SR_CLI_BAD_FLAG       Command terminated due to user          #
#                            specifying an invalid flag.             #
#   5  SR_CLI_USER_ERROR     Command terminated due to a user error. #
#                            For example specifying an undefined     #
#                            table to be modified.                   #
#                                                                    #
# Examples:                                                          #
#   rmsrrow /TokenRingAdapters "Node==3"                             #
#   - remove all rows with Node equal to 3 from the table            #
#       TokenRingAdapters.                                           #
#                                                                    #
#--------------------------------------------------------------------#
# Parameters:                                                        #
#   stdin on command line                                            #
#                                                                    #
# Returns:                                                           #
#   stdout - help/usage statement                                    #
#   stderr - all verbose, trace and error messages                   #
#                                                                    #
# External Ref:                                                      #
#   Commands: $LSMSG                                                 #
#   Extensions:  CT::SR.pm CT::SRrc.pm                               #
#   Perl library routines: Getopts::Std                              #
#   SR cli routines: SR_cli_utils - init_session, error_exit         #
#                              printCEMsg                            #
#                              clean_session, set_session_variables  #
#                    SR_cli_rc - CLI return codes                    #
#                                                                    #
# Tab Settings:                                                      #
#   4 and tabs should be expanded to spaces before saving this file. #
#   in vi:  (:set ts=4  and   :%!expand -4)                          #
#                                                                    #
# Change Activity:                                                   #
#   000929 HGJ 383173831738317: Initial delivery.                    #
#                                                                    #
######################################################################

#--------------------------------------------------------------------#
# General Program Flow/Logic:                                        #
#                                                                    #
# A: Parse command line - get table name                             #
# B: Initialise session with registry, including changing the        #
#    current directory if a relative path name is given (use value   #
#    given in CT_SR_HOME.)                                           #
# C: Open table to be edited.                                        #
# D: Call CT::SR::delete_rows to delete rows if possible             #
# E: Clean up session table and tree                                 #
#                                                                    #
#--------------------------------------------------------------------#


#--------------------------------------------------------------------#
# Included libraries and extensions                                  #
#--------------------------------------------------------------------#
use lib "/usr/sbin/rsct/pm";
use locale;
use Getopt::Std;
use FileHandle;

use CT_cli_utils qw(printIMsg
                    printEMsg
);

use CT::SR;
use CT::SRrc;
use SR_cli_utils qw(init_session 
                    printCEMsg
                    $DEFAULT_GLOBAL_MOUNT_POINT
                    open_table  
                    clean_session
                    set_session_variables
                    error_exit
);
use SR_cli_rc qw(:return_codes);


#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
$TRUE           = 1;
$FALSE          = 0;

# Variables used to map opt_x variables produced by getopts
$Verbose        = $FALSE;
$Trace          = $FALSE;

# Messaging Globals
$PROGNAME       = "rmsrrow";            # Program Name for messages
$MSGCAT         = "srcli.cat";          # msg catalogue for this cmd

$CTDIR          = "/usr/sbin/rsct";     # Cluster directory path
$CTBINDIR       = "$CTDIR/bin";         # Cluster Bin directory path
$LSMSG          = "$CTBINDIR/ctdspmsg"; # Display message routine
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps";  # Msg map path for $LSMSG
%Cleanup = ();                          # Hash of items to cleanup
                                        # {Session} $session to term

#--------------------------------------------------------------------#
# My Variables                                                       #
#--------------------------------------------------------------------#
# Variables used with extensions
my $Table_handle   = "";   

# Initialised to CT::SR::tree_handle_t class in init_session
my $Tree_handle    = ""; 

my $rc             = 0;            # assume good return code
my $Table_name     = "";
my $Table          = "";
my $Set_work_dir   = $FALSE;       
my $Selection_string = "";         # used to define rows for removal
my $Mount_point    = $DEFAULT_GLOBAL_MOUNT_POINT;


#--------------------------------------------------------------------#
# Main Code                                                          #
#--------------------------------------------------------------------#
# TODO: Many verbose statements in this code will eventually by
# Trace statements when the facility is available as a Perl CLI
# (feature 48401)
# TODO: security on access to the table can not be further defined
# until after a security design has been implemented for the SR.
# ( feature 48402 ) Until then, the table is opened with the
# minimum security necessary to complete the command.
# TODO: FFDC handling will be implemented in Feature 48397.


# Parse the command line, exit if there are errors
($rc, $Table_name, $Selection_string) = parse_cmd_line(); 
($rc == 0) || error_exit($rc);

if ($Verbose) {
    $Command_line_input = "\" $Table_name\n $Selection_string\"";
    printIMsg("IMsgrmsrrowCommandLineInput", $Command_line_input);
}   


# Establish registry session if possible
($Set_work_dir, $Table) = set_session_variables($Table_name);
($rc,$Tree_handle) = init_session($Set_work_dir);
($rc == 0) || error_exit($rc);

# Add session tree to cleanup hash
$Cleanup{Session} = $Tree_handle;


# Open the table to be edited
($rc, $Table_handle) = open_table($Tree_handle, $Table,
                        $Table_name, SR_METADATA);
($rc == 0) || error_exit($rc);

# Add the session table to the cleanup hash
push @{$Cleanup{Tables}}, $Table_handle;


$Verbose && 
    printIMsg("IMsgrmsrrowRemovingRows", $Selection_string, 
                    $Table_name);

$Trace && print STDERR "Calling CT::SR::delete_rows\n";
$rc = CT::SR::delete_rows($Table_handle, $Selection_string);
$Trace && print STDERR "CT::SR::delete_rows return code $rc\n";

$rc = error_check("sr_delete_rows", $rc, $Table_name);
($rc == 0) || error_exit($rc);


# Clean session and exit with the least non-zero error code
$rc = clean_session($Tree_handle, $Mount_point, $Table_handle);

# Clear the cleanup hash so clean_session isn't executed again
%Cleanup = ();
($rc == 0) || error_exit($rc);

# Return code is 0 here
exit $rc;


#--------------------------------------------------------------------#
# End Main Code                                                      #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# parse_cmd_line:                                                    #
#   Uses getopts() to grab flags on the command line, collects       #
#   table and selection string information to pass back to main      #
#   program                                                          #
#                                                                    #
# Return values:                                                     #
#   $local_rc - local return code 0 if OK, > 0 if error              #
#   $table_name - table name to be added                             #
#   $selection_string - string defining rows to be removed           #
#                                                                    #
# Global variables modified:                                         #
#   $opt_h, $opt_V, $opt_T - by getopts                              #
#   $Verbose - if $opt_V is set                                      #
#   $Trace - if $opt_T is set                                        #
#   @ARGV - all input from this global array                         #
#--------------------------------------------------------------------#
sub parse_cmd_line
{
my $local_rc = 0;
my $table_name = "";
my $select_string = "";
my %opts = ();

if (getopts('hTV', \%opts) == 0) {      # parse input flags
    printCEMsg("EMsgSRcliInvalidFlag");
    print_usage();
    return SR_CLI_BAD_FLAG;
}                   

# Print usage and exit if requested
if (defined $opts{h}) {   
    print_usage();
    exit(0);
}

# Set Trace flag if requested
if (defined $opts{T}) {
    $Trace = $TRUE;
}

# Set Verbose flag if requested
if (defined $opts{V}) {
    $Verbose = $TRUE;
}

# Grab the table name from the command line
$table_name = shift @ARGV;

# Scan for basic selection string operators to see if
# the table name was missed 
if ((!$table_name ) || ( $table_name =~ /(=|>|<|\?)/)) {
    printCEMsg("EMsgSRcliNoTableName");
    print_usage();
    return SR_CLI_BAD_OPERAND;
}

# This next line assumes the selection string is encased
# in quotes on the command line.
$select_string = shift @ARGV;
if (!$select_string) {
    printCEMsg("EMsgSRcliNoSelectionString");
    print_usage();
    return SR_CLI_BAD_OPERAND;  
}

return($local_rc , $table_name, $select_string);
}   # end parse_cmd_line


#--------------------------------------------------------------------#
# error_check:                                                       #
#   Checks the return code from the SR function.  If an error is     #
#   detected appropriate error messages will be displayed and        #
#   SR CLI return code set.                                          #
#                                                                    #
# Parameters:                                                        #
#   $sr_function  - Name of the SR function that was called and      #
#                   whose error code we are checking.                #
#   $sr_rc        - SR function return code.                         #
#   $table_name   - Name of the table trying to create.              #
#                                                                    #
# Return values:                                                     #
#   None.                                                            #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub error_check
{
my ($sr_function, $sr_rc, $table_name) = @_;
my $rc = 0;

if ($sr_rc != 0) {
    if ($sr_rc == SR_NO_PERMISSION) {
        printEMsg("EMsgrmsrrowNoPermission", $table_name);
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_CONNECTION_LOST) {
        printCEMsg("EMsgSRcliConnectionLost");
        $rc = SR_CLI_REGISTRY_ERROR;
    }
    elsif ($sr_rc == SR_NO_TABLE) {
        printCEMsg("EMsgSRcliTableNotFound", $table_name);
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_NO_DATA) {
        printEMsg("EMsgrmsrrowRowNotFound");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_UNMATCHING_PARENTHESIS) {
        printCEMsg("EMsgSRcliSEUnmatchingParens");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_NO_COLUMN) {
        printCEMsg("EMsgSRcliSENoColumn");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_ILLEGAL_COLUMN_NAME) {
        printCEMsg("EMsgSRcliSEIllegalColumnName");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_INVALID_TYPE_VARIABLE) {
        printCEMsg("EMsgSRcliSEInvalidTypeVar");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_UNMATCHING_TYPE_VARIABLE) {
        printCEMsg("EMsgSRcliSEUnmatchingTypeVar");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_INVALID_OPERATOR) {
        printCEMsg("EMsgSRcliSEInvalidOperator");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_INVALID_COMPARISON) {
        printCEMsg("EMsgSRcliSEInvalidComparison");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_ILLEGAL_SELECTION_STRING) {
        printCEMsg("EMsgSRcliSEIllegalSS");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_EXTRA_CHARS) {
        printCEMsg("EMsgSRcliSEExtraChars");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_NO_VAR_PARAMETER) {
        printCEMsg("EMsgSRcliSENoVarParameter");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_ILLEGAL_RANGE) {
        printCEMsg("EMsgSRcliSEIllegalRange");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_ILLEGAL_RANGE_LIST) {
        printCEMsg("EMsgSRcliSEIllegalRangeList");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_ILLEGAL_STRING_CONSTANT) {
        printCEMsg("EMsgSRcliSEIllegalStringConstant");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_NULL_STRING_CONSTANT) {
        printCEMsg("EMsgSRcliSENullStringConstant");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_ILLEGAL_NUMERIC_CONSTANT) {
        printCEMsg("EMsgSRcliSEIllegalNumericConstant");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_NULL_NUMERIC_CONSTANT) {
        printCEMsg("EMssrclirSENullNumericConstant");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_SE_ILLEGAL_REGEX) {
        printCEMsg("EMsgSRcliSEIllegalRegex");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc == SR_NULL_POINTER) {
        printEMsg("EMsgSRcliSSNullPointer");
        $rc = SR_CLI_USER_ERROR;
    }
    elsif ($sr_rc < 0) {
        # TODO: temporary check for selection string errors:
        # Waiting on code from
        print STDERR "rmsrtbl: selection string error\n";
        $rc = SR_CLI_USER_ERROR;
    }
    else {
        printEMsg("EMsgrmsrrowErrorRemovingRow", $table_name);
        printCEMsg("EMsgSRcliSRCommandFailure", $sr_function, $sr_rc);
        $rc = SR_CLI_REGISTRY_ERROR;
    }
}

return ($rc);
}   # end error_check


#--------------------------------------------------------------------#
# print_usage : print the usage statement (syntax) to stdout.        #
#   See this command's prologue syntax section for current usage.    #
#--------------------------------------------------------------------#
sub print_usage
{
printIMsg("IMsgrmsrrowUsage");
}   # end print_usage


#--------------------------------------------------------------------#
# End File                                                           #
#--------------------------------------------------------------------#
